home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / 3dlib15.zip / RTOBJ.PAS < prev    next >
Pascal/Delphi Source File  |  1992-10-27  |  33KB  |  780 lines

  1. (******************************************************************************
  2. *                                    rtObj                                    *
  3. *      please notice -                                                        *
  4. *      this unit includes both the object3d unit, and the superobj unit,      *
  5. *      and it is used with no reference to the window GUI library,            *
  6. *      uses project3, instead of prjWind                                      *
  7. ******************************************************************************)
  8. Unit rtObj;
  9.  
  10. (*******************************************************************************
  11. *                                 3D Objects                                   *
  12. *                                 ----------                                   *
  13. *                                                                              *
  14. *   A 3D object is a collection of points and lines in the 3D universe,        *
  15. *   that represent the body we want to draw on the screen.                     *
  16. *   A 3D object is allways centered around point (0, 0, 0) in the 3D universe. *
  17. *   (Its center of gravity assuming it is has a uniform weight distribution    *
  18. *    is in point (0, 0, 0)                                                     *
  19. *   At any moment during the object's life, we know it's distance from the     *
  20. *   origin, And it's rotation using reveres rotation CTM.                      *
  21. *                                                                              *
  22. *   3D Object methods:                                                         *
  23. *      constructor Open                                                        *
  24. *      destructor  CloseMe                                                     *
  25. *      procedures: Rotate, Scale, Move, Show, Hide, Load, Save                 *
  26. *                  SetToOrigin, Paint                                          *
  27. *                                                                              *
  28. *******************************************************************************)
  29.  
  30. interface
  31.  
  32. uses
  33.     Graph
  34.     ,Ctm3d
  35.     ,hdr3d
  36.     ,project3
  37.     ;
  38.  
  39. type
  40.     f_real = file of real;
  41.  
  42.     {===================================================================}
  43.     {  Base object is the base class for 3D-objects. some functions     }
  44.     { are dummy virtual do-nothing, which are are implemented only for  }
  45.     { the descendend objects derived from BaseObject                    }
  46.     {===================================================================}
  47.  
  48.     BaseObjectPtr = ^BaseObject;
  49.     BaseObject = object
  50.        MyCtm       : Ctm;      { This CTM applied to the object gives the  }
  51.                                {  objects Position after transformations   }
  52.        Name        : String;   { Identifies the object                     }
  53.        myColor     : word;     { Main color for the object                 }
  54.        Location    : point3d;  { Central of gravity in real space          }
  55.        scrPntUpdt  : boolean;  { True if screen points updated             }
  56.  
  57.        constructor open(myName : string; color : word);
  58.        destructor  CloseMe; virtual;
  59.        procedure   show; virtual;
  60.        procedure   hide; virtual;
  61.        procedure   paint; virtual; {in specified color}
  62.        procedure   updateScreenPoints; virtual; {transform object 3D -> 2D}
  63.        procedure   move(axis : axisType; by : real); virtual;
  64.        procedure   translate(dx, dy, dz : integer); virtual;
  65.                {multy dimentional move in 1 call}
  66.        procedure   scale(axis : axisType; factor : real); virtual;
  67.        procedure   allScale(sx, sy, sz : real); virtual;
  68.                {multy dimentional scale in 1 call}
  69.        procedure   rotate(axis : axisType; deg : real); virtual;
  70.  
  71.        procedure   goto3dPos(x, y, z : real); virtual; {translate to absolute place}
  72.        procedure   setToOrigin; virtual;
  73.                {translate to 0,0,0, update points, and set myCtm to unit}
  74.        procedure   calcLocation; virtual; {set Location to central gravity}
  75.        procedure   deleteTransform; virtual; {set MyCtm to unit}
  76.  
  77.        function load : word; virtual; {from disk}
  78.        function save : word; virtual; {to   disk}
  79.        procedure writeMe(var elementFile : f_real); virtual; {to disk .. without opening file..}
  80.        procedure readMe(var elementFile : f_real); virtual;
  81.     end;
  82.     {===================================================================}
  83.     { Obj3d is an object which represents a 3-D object with a poligon  }
  84.     {  mesh.                                                           }
  85.     {===================================================================}
  86.  
  87.     Obj3dPtr = ^Obj3d;
  88.     Obj3d = object(BaseObject)
  89.        Points      : array[1..MaxPoints] of point3d;
  90.        Lines       : array[1..MaxLines]   of Line3d;
  91.        scrPoints   : array[1..MaxPoints] of screenPoints;
  92.        NumOfLines  : integer;
  93.        NumOfPoints : integer;
  94.        ReverseRot  : Ctm;  { Saves only the reverse rotations }
  95.        unReverseRot: Ctm;  { reverse of the above}
  96.  
  97.        constructor open(myName : string; ref : point3d; color : word);
  98.        destructor  CloseMe; virtual;
  99.        procedure   paint; virtual; {in specified color}
  100.        procedure   updateScreenPoints; virtual; {transform object 3D -> 2D}
  101.  
  102.        procedure   calcLocation; virtual; {set Location to central gravity}
  103.        procedure   setToOrigin; virtual;
  104.  
  105.        procedure writeMe(var elementFile : f_real); virtual;
  106.        procedure readMe(var elementFile : f_real); virtual;
  107.     end;
  108.  
  109. const
  110.    maxSubObjects = 15;
  111.  
  112. type
  113.     complexObjPtr = ^complexObj;
  114.     ComplexObj = object(BaseObject)
  115.        childs      : array [1..maxSubObjects] of obj3dPtr;
  116.        ctms        : array [1..maxSubObjects] of ctm;
  117.        numOfChilds : integer; {counter of # of obj3d childs}
  118.  
  119.        constructor open(myName : string; color : word);
  120.        destructor  closeMe; virtual;
  121.        procedure   updateScreenPoints; virtual;
  122.        procedure   writeMe(var elementFile : f_real); virtual;
  123.        procedure   readMe(var elementFile : f_real); virtual;
  124.        procedure   calcLocation; virtual;
  125.        procedure   paint; virtual;
  126.        procedure   move(axis : axisType; by : real); virtual;
  127.        procedure   rotate(axis : axisType; deg : real); virtual;
  128.        procedure   scale(axis : axisType; factor : real); virtual;
  129.  
  130.        function    addSubObject(myName : string; refPoint : point3d) : word;
  131.        function    getChildPtr(index : integer) : obj3dPtr;
  132.        procedure   rotateChild(child : integer; axis : axisType;
  133.                                        deg : real);
  134.        procedure   scaleChild(child : integer; axis : axisType;
  135.                                        factor : real);
  136.        procedure   moveChild(child : integer; axis : axisType;
  137.                                by : real);
  138.     end;
  139.  
  140.  
  141. implementation
  142.  
  143.  
  144.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  145.     {                     BaseObject implementation                        }
  146.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  147.  
  148. (*******************************************************************************
  149. *                              BaseObject.Open                                 *
  150. *******************************************************************************)
  151. constructor BaseObject.Open;
  152. begin
  153.     name      := myName;
  154.     myColor   := color;
  155.     location  := ZeroPoint;
  156.     MyCtm.SetUnit;
  157. end; {baseObject.open}
  158.  
  159. (*******************************************************************************
  160. *                             BaseObject.CloseMe                               *
  161. *******************************************************************************)
  162. destructor BaseObject.CloseMe;
  163. begin
  164.     { I'm here so my children will Close-themselfs properly }
  165. end; {baseObject.closeMe}
  166.  
  167. (*******************************************************************************
  168. *                              BaseObject.move                                 *
  169. *******************************************************************************)
  170. procedure BaseObject.move(axis : axisType; by: real);
  171. begin
  172.        case axis of
  173.                x : begin
  174.                        myCtm.translateX(by);
  175.                        location.x :=location.x+by;
  176.                    end;
  177.                y : begin
  178.                        myCtm.translateY(by);
  179.                        location.y :=location.y+by;
  180.                    end;
  181.                z : begin
  182.                        myCtm.translateZ(by);
  183.                        location.z :=location.z+by;
  184.                    end;
  185.        end; {case}
  186.        scrPntUpdt := False;
  187. end; {BaseObject.move}
  188.  
  189. (*******************************************************************************
  190. *                            BaseObject.translate                              *
  191. *******************************************************************************)
  192. procedure BaseObject.translate(dx, dy, dz : integer);
  193. begin
  194.        myCtm.translate(dx,dy,dz);
  195.        location.x :=location.x+dx;
  196.        location.y :=location.y+dy;
  197.        location.z :=location.z+dz;
  198.        scrPntUpdt := False;
  199. end; {BaseObject.translate}
  200.  
  201. {use this routine when you know you need to translate more then one axis
  202.        before painting, you will use only one call, which will probably be
  203.        faster, and make your program easier to read, and maintain}
  204.  
  205. (*******************************************************************************
  206. *                              BaseObject.show                                 *
  207. *******************************************************************************)
  208. procedure BaseObject.show;
  209. begin
  210.     setColor(myColor);
  211.     paint;
  212. end; {baseObject.show}
  213.  
  214. (*******************************************************************************
  215. *                              BaseObject.hide                                 *
  216. *******************************************************************************)
  217. procedure BaseObject.hide;
  218. begin
  219.     setColor(0); {backGround}
  220.     paint;      {at this color}
  221. end; {baseObject.hide}
  222.  
  223. (*******************************************************************************
  224. *                              BaseObject.Paint                                *
  225. *******************************************************************************)
  226. procedure BaseObject.Paint;
  227. begin
  228.     if (not(scrPntUpdt)) then
  229.        updateScreenPoints;
  230.     { alas,  BaseObject cannot really paint becuase it does not have   }
  231.     { screen points (what a shame ...)                                 }
  232. end; {baseObject.paint}
  233.  
  234. (*******************************************************************************
  235. *                       BaseObject.UpdateScreenPoints                          *
  236. *******************************************************************************)
  237. procedure BaseObject.UpdateScreenPoints;
  238. begin
  239.     scrPntUpdt := True; { Have no screen points or any other points, so     }
  240.                         { points are already updated (I think)              }
  241. end; {updateScreenPoints}
  242.  
  243. (*******************************************************************************
  244. *                              BaseObject.scale                                *
  245. *******************************************************************************)
  246. procedure BaseObject.scale(axis : axisType; factor : real);
  247. begin
  248.        myCtm.translate(-location.x,-location.y,-location.z);
  249.        case axis of
  250.                x : myCtm.scaleX(factor);
  251.                y : myCtm.scaleY(factor);
  252.                z : myCtm.scaleZ(factor);
  253.        end; {scale}
  254.        myCtm.translate(location.x,location.y,location.z);
  255.        scrPntUpdt := False;
  256. end; {baseObject.scale}
  257.  
  258. (*******************************************************************************
  259. *                            BaseObject.allScale                               *
  260. *******************************************************************************)
  261. procedure BaseObject.allScale(sx,sy,sz : real);
  262. begin
  263.     myCtm.translate(-location.x, -location.y, -location.z);
  264.     myCtm.scale(sx,sy,sz);
  265.     myCtm.translate(location.x, location.y, location.z);
  266.     scrPntUpdt := False;
  267. end; {allScale}
  268. {call this routine to scale more then one axis at a time, with a single call}
  269.  
  270. (*******************************************************************************
  271. *                            BaseObject.goto3dPos                              *
  272. *******************************************************************************)
  273. procedure BaseObject.goto3dPos;
  274. begin
  275.        translate(round(x - location.x), round(y - location.y)
  276.                        , round(z - location.z));
  277. end; {baseObject.goto3dPos}
  278.  
  279. (*******************************************************************************
  280. *                           BaseObject.setToOrigin                             *
  281. *******************************************************************************)
  282. procedure BaseObject.setToOrigin;
  283. begin
  284.     goto3dPos(0, 0, 0);
  285.     myCtm.setUnit;
  286.     location := zeroPoint;
  287. end; {BaseObject.setToOrign}
  288.  
  289. (*******************************************************************************
  290. *                          BaseObject.CalcLocation                             *
  291. *******************************************************************************)
  292. procedure BaseObject.CalcLocation;
  293. begin
  294.     location := zeroPoint; { What else could it be when there are no points ?}
  295. end; {baseObject.calcLocation}
  296.  
  297. (*******************************************************************************
  298. *                         BaseObject.deleteTransform                           *
  299. *******************************************************************************)
  300. procedure BaseObject.deleteTransform;
  301. begin
  302.     myCtm.setUnit;
  303.     scrPntUpdt := false;
  304. end; {baseObject.deleteTransform}
  305.  
  306. (******************************************************************************
  307. *                              BaseObject.rotate                              *
  308. ******************************************************************************)
  309. procedure BaseObject.rotate;
  310. begin
  311.        myCtm.translate(-location.x,-location.y,-location.z);
  312.        case axis of
  313.                x :     myCtm.rotateX(deg);
  314.                y :     myCtm.rotateY(deg);
  315.                z :     myCtm.rotateZ(deg);
  316.        end; {case}
  317.        myCtm.translate(location.x,location.y,location.z);
  318.  
  319.        {rotation means : go to origin (translate -location),
  320.                          rotate       (rotate axis degrees),
  321.                          go to prev pos (translate location);
  322.        }
  323.  
  324.        scrPntUpdt := False;
  325. end; {BaseObject.rotate, see interface for comments}
  326.  
  327. (******************************************************************************
  328. *                               baseObject.load                               *
  329. ******************************************************************************)
  330. function baseObject.load;
  331. var
  332.     elementFile : f_real;
  333.     errC       : word;
  334. begin
  335.     {$i-} {supposed to be so, just making sure}
  336.     assign(elementFile,name);
  337.     reset(elementFile); {o.k. open it}
  338.     errC := ioResult;
  339.     load := errC;
  340.     if (errC = 0) then begin
  341.        readMe(elementFile);
  342.        errC := ioResult;
  343.        load := errC;
  344.        close(elementFile);
  345.        calcLocation;
  346.        scrPntUpdt := false;
  347.     end; {if}
  348. end; { baseObject.load}
  349.  
  350. (******************************************************************************
  351. *                               baseObject.save                               *
  352. ******************************************************************************)
  353. function baseObject.save;
  354. var
  355.     elementFile : f_real;
  356.     errC       : word;
  357. begin
  358.     {$i-} {supposed to be so, just making sure}
  359.     assign(elementFile,name);
  360.     rewrite(elementFile); {o.k. open it}
  361.     errC := ioResult;
  362.     save := errC;
  363.     if (errC = 0) then begin
  364.        writeMe(elementFile);
  365.        errC := ioResult; save := errC;
  366.        close(elementFile);
  367.     end; {if}
  368. end; {baseObject.save}
  369.  
  370. (******************************************************************************
  371. *                             baseObject.writeMe                              *
  372. ******************************************************************************)
  373. procedure baseObject.writeMe;
  374. begin
  375.    {override by descendents }
  376. end; {baseObject.writeMe}
  377.  
  378. (******************************************************************************
  379. *                              baseObject.readMe                              *
  380. ******************************************************************************)
  381. procedure baseObject.readMe;
  382. begin
  383.    {override by descendents }
  384. end; {baseObject.readMe}
  385.  
  386.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  387.     {                        Obj3d implementation                          }
  388.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  389.  
  390.  
  391. (*******************************************************************************
  392. *                                 Obj3d.open                                   *
  393. *******************************************************************************)
  394. constructor Obj3d.open;
  395. begin
  396.     BaseObject.Open(myName, color);
  397.     scrPntUpdt := False; {not calculated yet}
  398.     numOfLines := 0;
  399.     numOfPoints := 0;
  400.     myCtm.setUnit; {initialize to unit matrix}
  401.     reverseRot.setUnit;
  402.     unReverseRot.setUnit;
  403. end; {Obj3d.open}
  404.  
  405. (*******************************************************************************
  406. *                               Obj3d.CloseMe                                  *
  407. *******************************************************************************)
  408. destructor Obj3d.CloseMe;
  409. begin
  410. end;  {Obj3d.Close}
  411.  
  412.  
  413. (*******************************************************************************
  414. *                          Obj3d.updateScreenPoints                            *
  415. *******************************************************************************)
  416. procedure Obj3d.updateScreenPoints;
  417. var i : integer;
  418.     p : point3d;
  419. begin
  420.     for i := 1 to numOfPoints do begin
  421.        myCtm.transform(p,points[i]); {transform by ctm}
  422.        calcPoint(p, scrPoints[i]);
  423.     end; {for}
  424.     scrPntUpdt := True; {make sure for next time..}
  425.            {make all points ready}
  426. end; {obj3d.updateScreenPoints}
  427.  
  428. (*******************************************************************************
  429. *                                Obj3d.paint                                   *
  430. *******************************************************************************)
  431. procedure Obj3d.paint;
  432. {do the actual painting here}
  433. var
  434.     i : integer;
  435. begin
  436.     if ((numOfPoints = 0) or (numOfLines = 0)) then exit;
  437.     if (not(scrPntUpdt)) then
  438.        updateScreenPoints;
  439.     for i := 1 to numOfLines do
  440.        line(   scrPoints[lines[i].fromP].sX,
  441.                scrPoints[lines[i].fromP].sY,
  442.                scrPoints[lines[i].toP].sX,
  443.                scrPoints[lines[i].toP].sY  );
  444.     {it should be noted that calcPoint has to convert points to integers}
  445. end; {obj3d.paint}
  446.  
  447. (******************************************************************************
  448. *                                obj3d.readMe                                 *
  449. ******************************************************************************)
  450. procedure obj3d.readMe;
  451. var
  452.     tmp1,tmp2  : real;
  453.     i,j        : byte;
  454. begin
  455.        read(elementFile, tmp1);
  456.        numOfPoints := trunc(tmp1);
  457.        for j := 1 to numOfPoints do begin
  458.            read(elementFile, points[j].x);
  459.            read(elementFile, points[j].y);
  460.            read(elementFile, points[j].z);
  461.        end; {for}
  462.        read(elementFile, tmp1);
  463.        numOfLines := trunc(tmp1);
  464.        for j := 1 to numOfLines do begin
  465.            read(elementFile, tmp1, tmp2);
  466.            lines[j].fromP := trunc(tmp1);
  467.            lines[j].toP   := trunc(tmp2);
  468.        end; {for}
  469. end; {obj3d.readMe}
  470.  
  471. (******************************************************************************
  472. *                                obj3d.writeMe                                *
  473. ******************************************************************************)
  474. procedure obj3d.writeMe;
  475. var
  476.     tmp1,tmp2  : real;
  477.     i,j        : byte;
  478. begin
  479.        tmp1 := numOfPoints;
  480.        write(elementFile, tmp1);
  481.        for j := 1 to numOfPoints do begin
  482.            write(elementFile, points[j].x);
  483.            write(elementFile, points[j].y);
  484.            write(elementFile, points[j].z);
  485.        end; {for}
  486.        tmp1 := numOfLines;
  487.        write(elementFile, tmp1);
  488.        for j := 1 to numOfLines do begin
  489.            tmp1 := lines[j].fromP;
  490.            tmp2 := lines[j].toP;
  491.            write(elementFile, tmp1, tmp2);
  492.        end;
  493. end; {obj3d.writeMe}
  494.  
  495. (*******************************************************************************
  496. *                             obj3d.calcLocation                               *
  497. *******************************************************************************)
  498. procedure obj3d.calcLocation;
  499. var
  500.        ce : point3d;
  501.        p  : point3d;
  502.        i  : integer;
  503. begin
  504.        ce := zeroPoint; { (0, 0, 0) -> ce }
  505.        for i := 1 to numOfPoints do begin
  506.                myCtm.transform(p, points[i]);
  507.                ce.x := ce.x + p.x;
  508.                ce.y := ce.y + p.y;
  509.                ce.z := ce.z + p.z;
  510.        end; {for}
  511.        location.x := ce.x / numOfPoints;
  512.        location.y := ce.y / numOfPoints;
  513.        location.z := ce.z / numOfPoints;
  514. end; {obj3d.calcLocation}
  515.  
  516. (*******************************************************************************
  517. *                             Obj3d.setToOrigin                                *
  518. *******************************************************************************)
  519. procedure Obj3d.setToOrigin;
  520. var
  521.        i : integer;
  522.        p : point3d;
  523. begin
  524.     goto3dPos(0, 0, 0);
  525.     for i := 1 to numOfPoints do begin
  526.            myCtm.transform(p, points[i]);
  527.            points[i] := p;
  528.     end; {for}
  529.     scrPntUpdt := False; (** Instead of that THING above **)
  530.     myCtm.setUnit;
  531.     location := zeroPoint;
  532. end; {BaseObject.setToOrign}
  533.  
  534. (*******************************************************************************
  535. *                              ComplexObj.Open                                 *
  536. *******************************************************************************)
  537. constructor ComplexObj.Open;
  538. begin
  539.     BaseObject.Open(myName, color);
  540.     numOfChilds := 0;
  541. end; {complexObj.open}
  542.  
  543. (*******************************************************************************
  544. *                             ComplexObj.CloseMe                               *
  545. *******************************************************************************)
  546. destructor ComplexObj.CloseMe;
  547. var
  548.        i : integer;
  549.  
  550. begin
  551.        for i := 1 to numOfChilds do
  552.                dispose(childs[i],closeMe);
  553.        baseObject.closeMe;
  554. end; {complexObj.closeMe}
  555.  
  556. (*******************************************************************************
  557. *                          ComplexObj.addSubObject                             *
  558. *******************************************************************************)
  559. function ComplexObj.addSubObject;
  560. var
  561.     ret_code : word;
  562. begin
  563.        if (numOfChilds >= maxSubObjects) then begin
  564.                addSubObject := 255; {signal error}
  565.                exit;
  566.        end;
  567.        inc(numOfChilds);
  568.        childs[numOfChilds] := new(obj3dPtr, open(myName, zeroPoint, myColor));
  569.        ret_code := childs[numOfChilds]^.load;
  570.        if (ret_code = 0) then begin
  571.                with refPoint do
  572.                        childs[numOfChilds]^.translate(round(x),
  573.                                                round(y), round(z));
  574.                ctms[numOfChilds].copy(childs[numOfChilds]^.myCtm);
  575.        end; {if ret_c..}
  576.        addSubObject := ret_code;
  577. end; {complexObj.addSubObject}
  578.  
  579. (*******************************************************************************
  580. *                       complexObj.updateScreenPoints                          * 
  581. *******************************************************************************)
  582. procedure complexObj.updateScreenPoints;
  583. var
  584.     i : integer;
  585. begin
  586.     for i := 1 to numOfChilds do begin
  587.        childs[i]^.myCtm.multiply_2(ctms[i], myCtm);
  588.        childs[i]^.updateScreenPoints;
  589.     end;
  590.     scrPntUpdt := True;
  591. end; {complexObj.updateScreenPoints}
  592.  
  593. (*******************************************************************************
  594. *                           complexObj.getChildPtr                             *
  595. *******************************************************************************)
  596. function complexObj.getChildPtr;
  597. begin
  598.        getChildPtr := childs[index];
  599. end; {complexObj.getChildPtr}
  600.  
  601. (*******************************************************************************
  602. *                           ComplexObj.rotateChild                             *
  603. *******************************************************************************)
  604. procedure ComplexObj.rotateChild;
  605. begin
  606.     with childs[child]^ do begin
  607.        myCtm.copy(ctms[child]);
  608.        rotate(axis, deg);
  609.        ctms[Child].copy(MyCtm);
  610.        myCtm.Multiply(Self.myCtm);
  611.     end;
  612. end; {complexObj.rotateChild}
  613.  
  614. (*******************************************************************************
  615. *                           ComplexObj.scaleChild                              *
  616. *******************************************************************************)
  617. procedure ComplexObj.scaleChild;
  618. begin
  619.     with childs[child]^ do begin
  620.        myCtm.copy(ctms[child]);
  621.        scale(axis, factor);
  622.        ctms[Child].copy(MyCtm);
  623.        myCtm.Multiply(Self.myCtm);
  624.     end;
  625. end; {complexObj.scaleChild}
  626.  
  627. (*******************************************************************************
  628. *                            ComplexObj.moveChild                              *
  629. *******************************************************************************)
  630. procedure ComplexObj.moveChild;
  631. begin
  632.     with childs[child]^ do begin
  633.        myCtm.copy(ctms[child]);
  634.        move(axis, by);
  635.        ctms[Child].copy(MyCtm);
  636.        myCtm.Multiply(Self.myCtm);
  637.     end;
  638. end; {complexObj.moveChild}
  639.  
  640. (******************************************************************************
  641. *                              complexObj.paint                               *
  642. ******************************************************************************)
  643. procedure complexObj.paint;
  644. var
  645.        i : integer;
  646. begin
  647.     if (not(scrPntUpdt)) then
  648.        updateScreenPoints;
  649.     for i := 1 to numOfChilds do
  650.        childs[i]^.paint;
  651. end; {complexObj.paint}
  652.  
  653. (******************************************************************************
  654. *                             complexObj.writeMe                              *
  655. ******************************************************************************)
  656. procedure complexObj.writeMe;
  657. var
  658.        i : integer;
  659.        r : real;
  660. begin
  661.        r := 0.0 + numOfChilds;
  662.        write(elementFile, r);
  663.        for i := 1 to numOfChilds do
  664.                childs[i]^.writeMe(elementFile); {let all the kids write themselvs}
  665. end; {complexObj.writeMe}
  666.  
  667. (******************************************************************************
  668. *                              complexObj.readMe                              *
  669. ******************************************************************************)
  670. procedure complexObj.readMe;
  671. var
  672.        i : integer;
  673.        r : real;
  674. begin
  675.        read(elementFile, r);
  676.        numOfChilds := round(r);
  677.        for i := 1 to numOfChilds do begin
  678.               childs[i] := new(Obj3dPtr, Open('Child', ZeroPoint, myColor));
  679.               childs[i]^.readMe(elementFile);
  680.               childs[i]^.calcLocation;
  681.               ctms[i].setUnit;
  682.        end; {for}
  683. end; {complexObj.readMe}
  684.  
  685. (******************************************************************************
  686. *                           complexObj.calcLocation                           *
  687. ******************************************************************************)
  688. procedure complexObj.calcLocation;
  689. var
  690.        i : integer;
  691. begin
  692.        location := zeroPoint;
  693.        for i := 1 to numOfChilds do
  694.                with childs[i]^ do begin
  695.                        calcLocation;
  696.                        self.location.x := location.x + self.location.x;
  697.                        self.location.y := location.y + self.location.y;
  698.                        self.location.z := location.z + self.location.z;
  699.                end; {with}
  700.        with location do begin
  701.                x := x / numOfChilds;
  702.                y := y / numOfChilds;
  703.                z := z / numOfChilds;
  704.        end; {with..}
  705. end; {complexObj.calclocation}
  706.  
  707. (******************************************************************************
  708. *                               complexObj.move                               *
  709. ******************************************************************************)
  710. procedure complexObj.move;
  711. var
  712.        i : integer;
  713. begin
  714. (*       for i := 1 to numOfChilds do
  715.                with childs[i]^ do
  716.                        case axis of
  717.                                x : location.x := location.x + by;
  718.                                y : location.y := location.y + by;
  719.                                z : location.z := location.z + by;
  720.                        end; {case}  *)
  721.        baseObject.move(axis, by);
  722. end; {complexObj.move}
  723.  
  724. (******************************************************************************
  725. *                              complexObj.rotate                              *
  726. ******************************************************************************)
  727. procedure complexObj.rotate;
  728. var
  729.        i : integer;
  730.        sint, cost : real;
  731. begin
  732. (*       cost := cos(deg / 180.0 * 3.1415926535897932385);
  733.        sint := sin(deg / 180.0 * 3.1415926535897932385);
  734.        for i := 1 to numOfChilds do
  735.                with childs[i]^ do
  736.                        case axis of
  737.                                x : begin
  738.                                        location.y := location.y * cost -
  739.                                                location.z * sint;
  740.                                        location.z := location.y * sint +
  741.                                                location.z * cost;
  742.                                end; {x}
  743.                                y : begin
  744.                                        location.x := location.x * cost +
  745.                                                location.z * sint;
  746.                                        location.z := location.z * cost -
  747.                                                location.x * sint;
  748.                                end; {y}
  749.                                z : begin
  750.                                        location.x := location.x * cost -
  751.                                                location.y * sint;
  752.                                        location.y := location.y * cost +
  753.                                                location.x * sint;
  754.                                end; {z}
  755.                        end; {case} *)
  756.        baseObject.rotate(axis, deg);
  757. end; {complexObj.rotate}
  758.  
  759. (******************************************************************************
  760. *                              complexObj.scale                               *
  761. ******************************************************************************)
  762. procedure complexObj.scale;
  763. var
  764.        i : integer;
  765. begin
  766. (*       for i := 1 to numOfChilds do
  767.                with childs[i]^ do
  768.                        case axis of
  769.                                x : location.x := location.x * factor;
  770.                                y : location.y := location.y * factor;
  771.                                z : location.z := location.z * factor;
  772.                        end; {case} *)
  773.        baseObject.scale(axis, factor);
  774. end; {complexObj.scale}
  775.  
  776. (******************************************************************************
  777. *                                    end.                                     *
  778. ******************************************************************************)
  779. end.
  780.